using System;
using System.Collections.Generic;
using System.Text;
using Lidgren.Network;
using System.Threading;
using SolarWinds.Logic;

namespace SolarWinds
{
    class Client
    {
        NetClient client;
        NetBuffer buffer;

        public Player mOwnPlayer;
        public Dictionary<String, Player> mName2PlayersDict = new Dictionary<String, Player>();

        public void Initialize()
        {
            // create a client with a default configuration
            NetConfiguration config = new NetConfiguration("SolarWinds");
            
            client = new NetClient(config);
            client.SetMessageTypeEnabled(NetMessageType.ConnectionRejected, true);
            client.SetMessageTypeEnabled(NetMessageType.DebugMessage, true);
            //client.SetMessageTypeEnabled(NetMessageType.VerboseDebugMessage, true);
            client.Start();

            // Wait half a second to allow server to start up if run via Visual Studio
            Thread.Sleep(500);

            // Emit discovery signal
            client.DiscoverLocalServers(8930);

            // create a buffer to read data into
            buffer = client.CreateBuffer();
        }

        public void Shutdown()
        {
            client.Shutdown("Shutting down client");
        }

        public void Update()
        {
            NetMessageType type;

            // check if any messages has been received
            while (client.ReadMessage(buffer, out type))
            {
                switch (type)
                {
                    case NetMessageType.ServerDiscovered:
                        // just connect to any server found!

                        // make hail
                        NetBuffer buf = client.CreateBuffer();
                        buf.Write("[Client] Hail from " + Environment.MachineName);
                        client.Connect(buffer.ReadIPEndPoint(), buf.ToArray());
                        break;
                    case NetMessageType.ConnectionRejected:
                        Console.WriteLine("[Client] Rejected: " + buffer.ReadString());
                        break;
                    case NetMessageType.DebugMessage:
                    case NetMessageType.VerboseDebugMessage:
                        Console.WriteLine("[Client] " + buffer.ReadString());
                        break;
                    case NetMessageType.StatusChanged:
                        Console.WriteLine("[Client] New status: " + client.Status + " (" + buffer.ReadString() + ")");
                        if (client.Status == NetConnectionStatus.Connected)
                        {
                            // TODO Join (Game.mPlayernameEditBox.Text);
                        }
                        break;
                    case NetMessageType.Data:
                        Console.WriteLine("[Client] Data received from server");

                        MessageTypes msgType = (MessageTypes)buffer.ReadInt32();
                        if (msgType == MessageTypes.PLAYER_JOINED)
                        {
                            PlayerJoinedMessage msg = new PlayerJoinedMessage();
                            msg.FromBuffer(buffer);

                            PlayerJoined(msg);
                        }

                        break;
                }
            }
        }

        private void PlayerJoined(PlayerJoinedMessage msg)
        {
            Player newPlayer = new Player (msg.mPlayerName);

            
            // TODO if (Game.mPlayernameEditBox.Text == msg.mPlayerName)
            {
                mOwnPlayer = newPlayer;            
            }

            mName2PlayersDict.Add(msg.mPlayerName, newPlayer);

            foreach (KeyValuePair<String, Player> pair in mName2PlayersDict)
            {
                Console.WriteLine("[Client] Players: " + pair.Key);
            }
 	    }

        public void Send(NetworkMessage msg)
        {
            // Send chat message
            NetBuffer sendBuffer = new NetBuffer();
            msg.ToBuffer(sendBuffer);
            client.SendMessage(sendBuffer, NetChannel.ReliableInOrder1);
        }

        public void Join(String playerName)
        {
            PlayerJoinedMessage msg = new PlayerJoinedMessage(playerName);
            
            Send(msg);
        }


        public void Leave()
        {

        }

        public void MoveShip(/* TODO Position2D pos*/)
        {

        }
    }
}
